package initialize

import (
	"github.com/gin-gonic/gin"
	"io"
	"log"
	"melon/server/constant"
	"melon/server/global"
	"melon/server/service/sys_log_hook"
	"melon/server/utils/casbin_v2"
	"melon/server/utils/gorm_v2"
	"melon/server/utils/yml_config"
	"melon/server/utils/zap_factory"
	"os"
)

// 检查项目必须的非编译目录是否存在，避免编译后调用的时候缺失相关目录
func checkRequiredFolders() {
	//1.检查配置文件是否存在
	if _, err := os.Stat(global.BasePath + "/config/melon.yml"); err != nil {
		log.Fatal(constant.ErrorsMelonYamlNotExists + err.Error())
	}
	if _, err := os.Stat(global.BasePath + "/config/config.yml"); err != nil {
		log.Fatal(constant.ErrorsConfigYamlNotExists + err.Error())
	}
	if _, err := os.Stat(global.BasePath + "/config/gorm_v2.yml"); err != nil {
		log.Fatal(constant.ErrorsConfigGormNotExists + err.Error())
	}
	//2.检查db是否存在
	if _, err := os.Stat(global.BasePath + "/config/melon.db"); err != nil {
		log.Fatal(constant.ErrorsDatabaseNotExists + err.Error())
	}
}

func InitConfig() {

	// 检查配置文件以及日志目录等非编译性的必要条件
	checkRequiredFolders()

	// 启动针对配置文件(melon.yml)变化的监听， 配置文件操作指针，初始化为全局变量
	global.MelonYml = yml_config.CreateYamlFactory()
	global.MelonYml.ConfigFileChangeListen()
	// 启动针对配置文件(config.yml)变化的监听， 配置文件操作指针，初始化为全局变量
	global.ConfigYml = global.MelonYml.Clone("config")
	global.ConfigYml.ConfigFileChangeListen()
	// config>gorm_v2.yml 启动文件变化监听事件
	global.ConfigGormv2Yml = global.ConfigYml.Clone("gorm_v2")
	global.ConfigGormv2Yml.ConfigFileChangeListen()

	// 初始化全局日志句柄，并载入日志钩子处理函数
	global.ZapLog = zap_factory.CreateZapFactory(sys_log_hook.ZapLogHandler)

	// 根据配置初始化 gorm mysql 全局 *gorm.Db
	if global.ConfigGormv2Yml.GetInt("Gormv2.Mysql.IsInitGolobalGormMysql") == 1 {
		if dbMysql, err := gorm_v2.GetOneMysqlClient(); err != nil {
			log.Fatal(constant.ErrorsGormInitFail + err.Error())
		} else {
			global.GormDbMysql = dbMysql
		}
	}
	// 根据配置初始化 gorm sqlserver 全局 *gorm.Db
	if global.ConfigGormv2Yml.GetInt("Gormv2.Sqlserver.IsInitGolobalGormSqlserver") == 1 {
		if dbSqlserver, err := gorm_v2.GetOneSqlserverClient(); err != nil {
			log.Fatal(constant.ErrorsGormInitFail + err.Error())
		} else {
			global.GormDbSqlserver = dbSqlserver
		}
	}
	// 根据配置初始化 gorm postgresql 全局 *gorm.Db
	if global.ConfigGormv2Yml.GetInt("Gormv2.PostgreSql.IsInitGolobalGormPostgreSql") == 1 {
		if dbPostgre, err := gorm_v2.GetOnePostgreSqlClient(); err != nil {
			log.Fatal(constant.ErrorsGormInitFail + err.Error())
		} else {
			global.GormDbPostgreSql = dbPostgre
		}
	}
	// 根据配置初始化 gorm sqlite3 全局 *gorm.Db
	if global.ConfigGormv2Yml.GetInt("Gormv2.Sqlite.IsInitGolobalGormSqlite") == 1 {
		if dbSqlite, err := gorm_v2.GetOneSqliteClient(); err != nil {
			log.Fatal(constant.ErrorsGormInitFail + err.Error())
		} else {
			global.GormDbSqlite = dbSqlite
		}
	}

	// casbin 依据配置文件设置参数(IsInit=1)初始化
	if global.ConfigYml.GetInt("Casbin.IsInit") == 1 {
		var err error
		if global.Enforcer, err = casbin_v2.InitCasbinEnforcer(); err != nil {
			log.Fatal(err.Error())
		}
	}

	// gin log配置
	appDebug := global.ConfigYml.GetBool("AppDebug")
	if appDebug == false {
		//1.将日志写入日志文件
		gin.DisableConsoleColor()
		f, _ := os.Create(global.BasePath + global.ConfigYml.GetString("Logs.GinLogName"))
		gin.DefaultWriter = io.MultiWriter(f)
		gin.SetMode(gin.ReleaseMode)
	}
}
